package start.spring.basic.job.timer;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.github.pagehelper.util.StringUtil;

import lombok.extern.slf4j.Slf4j;
import start.spring.basic.dynamic.DynamicRedisDAO;
import start.spring.basic.job.common.JobConstant;
import start.spring.basic.job.quartz.TaskBean;
import start.spring.basic.job.quartz.TaskService;

/**
 * 
 * ****************************************************************************
 * 更新已加载job定时器
 *
 * @author(作者)：xuyongyun	
 * @date(创建日期)：2023年7月4日
 ******************************************************************************
 */
@Slf4j
@Component
@EnableScheduling
public class JobUpdateTimer {
	
	@Autowired
    private DynamicRedisDAO redis;
	
	@Autowired
	private TaskService taskService;
	
	/**
	 * jvm缓存上次更新时间戳
	 */
	private static Map<String,String> updateTimeStampMap = new HashMap<>();

	/**
	 * 异步更新已加载的job
	 *	每分钟检查一次是否需要更新
	 * @since           1.0
	 */
	@Scheduled(cron = "0 0/1 * * * ? ")
	public void updateLoadedJob() {
		List<TaskBean> taskList = this.taskService.getTaskFromDb();
		if(taskList!=null&&!taskList.isEmpty()) {
			for(TaskBean task:taskList) {
				try {
					//判断任务是否存在
					boolean jobExist = this.taskService.isJobExist(task);
					//任务存在
					if(jobExist) {
						//判断任务是否需要更新
						String key = JobConstant.JOB_UPDATE_PREFIX + task.getJobClass();
						//redis有更新记录
						if(this.redis.hasKey(null, key)) {
							boolean needUpdate = true;
							//redis中记录的时间戳
							String updateTimeStamp = this.redis.get(null, key);
							//redis中保存的值有问题
							if(StringUtil.isEmpty(updateTimeStamp)) {
								needUpdate = false;
							}else {
								if(updateTimeStampMap.containsKey(task.getJobClass())) {
									//jvm记录的时间戳与redis时间戳一致，说明已更新
									if(updateTimeStamp.equals(updateTimeStampMap.get(task.getJobClass()))) {
										needUpdate = false;
									}else {
										String dbCronTime = task.getCronTime();
										String jvmCronTime = this.taskService.getJob(task.getJobClass()).getCronTime();
										//调度策略未变，不需要更新
										if(dbCronTime.equals(jvmCronTime)) {
											needUpdate = false;
											updateTimeStampMap.put(task.getJobClass(), updateTimeStamp);
										}
									}
								}
							}
							
							//需要更新
							if(needUpdate) {
								this.taskService.updateJob(task);
								updateTimeStampMap.put(task.getJobClass(), updateTimeStamp);
							}
						}
					}
				} catch (SchedulerException e) {
					log.error("获取任务是否存在出错！", e);
				}
			}
		}
	}
}
